# encoding: utf-8
"""
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    created by lane.chang on '17/10/2024'
    comment: 流程节点
"""
from itertools import groupby
from sqlalchemy import func
from fastapi import APIRouter, Request, Query

from config import Config
from project.core.function import if_none, json_response
from project.lib.decorator import api_common, exec_duration
from project.lib.validators import DateStr, generate_validator
from project.model.database.flow import Flow, FlowProcess, FlowRole
from project.model.database.record import FlowRecord, FlowRecordLog
from project.service.record import RecordService


record_router = APIRouter(prefix='/u', tags=['user.record'])


@record_router.get('/flow/record/list', summary='服务记录列表')
@api_common(doc_replace=(('{0}', Config.ENV_DOC_FIX),))
@exec_duration(add_return=True)
async def get_flow_record_list(request: Request,
                               status: str = Query('', title='服务记录状态', description='init(待完成)/success(已完成)/cancel(已取消)'),
                               flow_role_id: int = Query(..., title='服务角色id'),
                               start_date: generate_validator(DateStr, blank_enable=True) = Query('', title='开始日期', description='格式: yyyy-mm-dd'),
                               end_date: generate_validator(DateStr, blank_enable=True) = Query('', title='结束日期', description='格式: yyyy-mm-dd'),
                               session=None):
    """
    **desc**: 服务记录列表

    **url**: http(s)://{0}.udicaria.com/u/flow/record/list

    **method**: GET

    **params**:

        <query>:
            status: 服务记录状态 init(待完成)/success(已完成)/cancel(已取消)
            flow_role_id: 服务角色id
            start_date: 开始日期
            end_date: 结束日期

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data: {
                num: 条数
                items: [
                    {
                        id: 服务记录id
                        code: 服务编号
                        room_no: 房间号
                        flow_id: 服务流程id
                        flow_name: 服务名称
                        status: 服务状态 init(待完成)/success(已完成)/cancel(已取消)
                        flow_process_name: 当前节点
                        status_logs: 已经过的服务节点列表
                        create_time: 发起时间
                    }
                ]
            }
            exec_time: 接口后端处理时长
        }
    """
    # 获取角色相关服务流程
    role = await FlowRole.fetch_one(session, wheres=(FlowRole.id == flow_role_id, ~FlowRole.is_deleted))
    if not role:
        return json_response()
    if role.phone:
        role_list = await FlowRole.fetch_all(session, wheres=(FlowRole.phone == role.phone, ~FlowRole.is_deleted))
        flow_ids = [v.flow_id for v in role_list]
    else:
        flow_ids = [role.flow_id]

    wheres = list()
    if status:
        wheres.append(FlowRecord.status == status)
    if start_date:
        wheres.append(FlowRecord.business_date >= start_date)
    if end_date:
        wheres.append(FlowRecord.business_date <= end_date)
    if flow_ids:
        wheres.append(FlowRecord.flow_id.in_(flow_ids))
    wheres.append(~FlowRecord.is_deleted)

    # num
    record = await FlowRecord.fetch_one(session,
                                        selects=(func.count(FlowRecord.id)),
                                        wheres=wheres)
    num = if_none(record[0], 0)

    # 批量查询服务记录和流程信息
    data = await FlowRecord.fetch_all(session,
                                      selects=(FlowRecord, Flow),
                                      joins=((Flow, Flow.id == FlowRecord.flow_id), ),
                                      wheres=wheres,
                                      orders=FlowRecord.update_time.desc())

    # 将生成器的结果转换为列表，避免第二次迭代时没有数据
    data_list = list(data)

    # 预先加载所有记录的状态日志列表，避免在循环中查询
    record_ids = [flow_record.id for flow_record, _ in data_list]
    record_logs = await FlowRecordLog.fetch_all(session, wheres=(FlowRecordLog.flow_record_id.in_(record_ids)), orders=(FlowRecordLog.id.desc()))
    # 确保按 flow_record_id 排序，groupby 的输入必须是排序后的数据，否则分组可能不完整
    record_logs = sorted(record_logs, key=lambda x: x.flow_record_id)
    status_dict = {flow_record_id: [v.flow_process_name for v in status_list] for flow_record_id, status_list in groupby(record_logs, key=lambda x: x.flow_record_id)}

    items = [{
        'id': flow_record.id,
        'code': flow_record.code,
        'room_no': flow_record.room_no,
        'flow_id': flow.id,
        'flow_name': flow.name,
        'status': flow_record.status,
        'flow_process_name': flow_record.flow_process_name,
        'status_logs': status_dict.get(flow_record.id, []),
        'create_time': flow_record.create_time,
    } for flow_record, flow in data_list]

    ret_data = {
        'num': num,
        'items': items
    }
    return json_response(data=ret_data)


@record_router.get('/flow/record/detail', summary='服务记录详情')
@api_common(doc_replace=(('{0}', Config.ENV_DOC_FIX),))
@exec_duration(add_return=True)
async def get_flow_record_detail(request: Request,
                                 flow_record_id: int = Query(..., title='服务记录id'),
                                 session=None):
    """
    **desc**: 服务记录详情

    **url**: http(s)://{0}.udicaria.com/u/flow/record/detail

    **method**: GET

    **params**:

        <query>:
            flow_record_id: 服务记录id

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data: {
                id: 服务记录id
                code: 服务记录编号
                flow_code: 服务流程编号
                flow_name: 服务流程名称
                flow_process_id: 流程状态id
                flow_process_name: 流程状态名称
                room_no: 房间号
                dev_id: 设备编号
                content: [
                    {
                        title: 项目名称
                        value: 项目值
                        items: [
                            {
                                title: 商品名
                                count: 商品数量
                                price: 商品单价
                                spec: [] 规格信息 [{"title": xxx, "items": [xxx, xxx, xxx]}, {"title": xxx, "items": [xxx, xxx, xxx]}]
                            }
                            ...
                        ]
                    }
                    ...
                ] 服务内容
                flow_record_logs: [
                    {
                        record_status: 节点
                        flow_process_id: 节点状态id
                        flow_process_name: 节点状态名称
                        record_status: 服务记录状态 init(待完成)/success(已完成)/cancel(已取消)
                        flow_role_name: 服务人员
                        flow_role_phone: 联系电话
                        create_time: 操作时间
                    }
                ] 流程状态

                invoice: {
                    room_number: 房间号
                    invoice_type: 发票类型(electronic(电子发票)/paper(纸质发票))
                    title_type: 抬头类型(enterprise(企业单位)/individual(个人/非企业单位)
                    invoice_title: 发票抬头
                    tax_number: 税号
                    email: 邮箱
                    bank_name: 开户银行
                    bank_account: 银行账号
                    company_address: 公司地址
                    company_phone: 公司电话
                } 发票信息
            }
            exec_time: 接口后端处理时长
        }
    """
    data = await RecordService.get_flow_record_detail(session, flow_record_id=flow_record_id)

    return json_response(data=data)
